#ifndef ORG_WXW0303_SYMBOL_DB_SYMNAMETABLE_H
#define ORG_WXW0303_SYMBOL_DB_SYMNAMETABLE_H

#include <memory>
#include <string>
#include <vector>
#include <utility>

#include "sym-info-table.h"

struct SymName {
    virtual const std::string& language() = 0;
    virtual const std::string& name() = 0;

    virtual ~SymName() = default;
};

/// SymNameTable 对象也是全局唯一的.
struct SymNameTable {
    /// 返回 name 语言对应的实例;若不存在,则返回空.
    static SymNameTable* instance(const std::string &language);
    static std::vector<std::string> supportLanguages();

    /**
     * 输出语言特定的帮助文档;即告诉用户在这个语言中,如何确定一个符号.
     * 框架对 help() 的使用:
     *    语言名;help();\n
     *    语言名;help();\n
     * 所以 help() 可以占据多行,但是最后一行不要带'\n',同时除第一行之外,其余行之前最好有
     * 4 空格的缩进.
     */
    virtual const std::string& help() = 0;
    virtual const std::string& language() = 0;
    virtual std::shared_ptr<SymName> getSymName(int argc,char **argv) = 0;
    virtual std::vector<std::pair<SymInfoTable::id_t,std::shared_ptr<SymName>>>
    find(std::shared_ptr<SymName>) = 0;
    virtual void add(SymInfoTable::id_t,std::shared_ptr<SymName>) = 0;

    virtual ~SymNameTable() = default;
};

struct STRH {
    typedef SymNameTable* (*RegisterFunc)();

    STRH(const std::string &language,RegisterFunc f_ptr);
};

#define LANGUAGE_REGISTER(lang,Class) \
    SymNameTable* __##Class##_Register_func() \
    { return new Class(); }        \
    STRH __##Class##_Register_obj{lang,__##Class##_Register_func}


#endif // ORG_WXW0303_SYMBOL_DB_SYMNAMETABLE_H
